<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="https://img2.jimu98.cn/blog/20200729222712.png">
  <link rel="icon" type="image/png" href="https://img2.jimu98.cn/blog/20200729222712.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="你会的越多,你不会的越多,我是积木,互联网的一只小菜鸡">
  <meta name="author" content="积木">
  <meta name="keywords" content="积木,jimu98,java,后端,jimu">
  <title>【java总结】计算机网络-HTTP - 积木 | 互联网的一只小菜鸡</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/github-gist.min.css" />
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_yg9cfy8wd6.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_pjno9b9zyxs.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/js/utils.js" ></script>
  <script data-ad-client="ca-pub-2806771379080352" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<meta name="generator" content="Hexo 4.2.1"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>jimu98</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/list/">
                <i class="iconfont icon-bookmark-fill"></i>
                导航
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/links/">
                <i class="iconfont icon-link-fill"></i>
                友链
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="view intro-2" id="background" parallax=true
         style="background: url('https://img2.jimu98.cn/blog/20200729222405.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container text-center white-text fadeInUp">
            <span class="h2" id="subtitle">
              
            </span>

            
              
  <div class="mt-3 post-meta">
    <i class="iconfont icon-date-fill" aria-hidden="true"></i>
    <time datetime="2020-07-29 20:06">
      2020年7月29日 晚上
    </time>
  </div>


<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      7.2k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      77
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <div class="post-content mx-auto" id="post">
            
            <article class="markdown-body">
              <h1 id="【java总结】计算机网络-HTTP篇"><a href="#【java总结】计算机网络-HTTP篇" class="headerlink" title="【java总结】计算机网络-HTTP篇"></a>【java总结】计算机网络-HTTP篇</h1><blockquote>
<p>本内容参考了多位大佬，几十篇博客整理出来的，方便自己的复习，同时有不全面，不正确的内容欢迎补充</p>
</blockquote>
<h2 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h2><p>这个协议对于网络工程师来说，他只是一个协议而已，但对于我们java工程师，或者前端工程师，或者其他非网络计算机从业者都太重要了。我们java开发的很大部分都是web应用，。我们对Web的操作都是通过HTTP协议来进⾏传 输数据的，前端也是很直接的利益相关（怎么有股知乎的味道。）总而言之，Http就是Web通信的基础，这是我们必学的。我一定要总结的全面，透彻。方便自己，方便大家。</p>
<h3 id="Http基本概念"><a href="#Http基本概念" class="headerlink" title="Http基本概念"></a>Http基本概念</h3><p>HTTP全称是 HyperText Transfer Protocal，即：超文本传输协议。是互联网上应用最为广泛的一种<strong>网络通信协议</strong>，它允许将超文本标记语言（HTML）文档从Web服务器传送到客户端的浏览器。目前我们使用的是<strong>HTTP/1.1 版本</strong>。</p>
<p>前面不是说了网络的分层概念吗，我们的HTTP协议是在最上层，也就是应⽤层。这是最贴近我们的程序员的层次。</p>
<blockquote>
<p>我们逐步一点点来看，解决一个又一个小概念，争取建立一个完整的HTTP体系</p>
<p>最终解决一个大的问题：在浏览器输入 URL 后发生了什么？</p>
</blockquote>
<h3 id="URI-和-URL-有什么区别？"><a href="#URI-和-URL-有什么区别？" class="headerlink" title="URI 和 URL 有什么区别？"></a>URI 和 URL 有什么区别？</h3><p>URI：统一资源标识符（Uniform Resource Identifier），就是在某一规则下能把一个资源独一无二地标识出来。它可以理解成是一个资源的名字，比如<code>积木</code>,<code>jimu98</code>甚至<code>jimu98@foxmail.com</code>或者是<code>aaa.html</code>，只要可以唯一的标识一个名字，那么我们就把他称作uri，甚至<code>https://www.jimu98.cn/aaa.html</code>也是一个URI(这个不是应该叫URL，别着急)</p>
<p>URI：统一资源标识符(uniform resource identifier)，比如<code>https://www.jimu98.cn/aaa.html</code>，</p>
<p>其实，我们可以发现，URI强调的是给资源标记命名，URL强调的是给资源定位，但是你会发现，URL显然比URI包含信息更多，我通过URL也可以知道自己的资源名字可能是<code>aaa.html</code>，并且我还知道了他的地址.</p>
<p>所以大多数情况下大家觉得给一个网络资源分别命名和给出地址太麻烦，干脆就用地址既当地址用，又当标记名用</p>
<p>所以，URL也充当了WWW万维网里面URI的角色，但是他比URI多了一层意义，我不光知道你叫什么，我还知道你在哪里。</p>
<p>我们在浏览器输入的都是URL，因为我们输入的目的是为了找到某一个资源。</p>
<h3 id="DNS：负责解析域名"><a href="#DNS：负责解析域名" class="headerlink" title="DNS：负责解析域名"></a>DNS：负责解析域名</h3><blockquote>
<p>当我们需要访问一个远程资源的时候，必然要和他建立连接(建立TCP，或者UDP连接，基于IP协议)</p>
<p>所以我们要知道他的地址，可是随着互联网的发展，越来越多的web应用进入大家视线，比如我们访问一些常用的网站，<code>www.baidu.com</code> <code>www.jd.com</code> 这些时候，我们明明输入的不是ip。</p>
<p>其实让我们记IP，也是可以访问的，但是你愿意记那么长的数字吗，反正我不愿意，于是乎DNS <code>域名解析协议</code> 诞生了，他就可以把一个特殊含义的域名转换成一个IP地址。</p>
<p>但是你想啊，你想要用baidu这个名字，别人也想，那到底该给谁呢。于是肯定有专门的管理机构去统一规范。</p>
<p>但是，我们还有一个叫做本地DNS的东西，通过配置Host文件，去自定义一个域名，实现本地映射。</p>
</blockquote>
<blockquote>
<p>DNS工作流程：</p>
<p>1、在浏览器中输入<a href="http://www.baidu.com" target="_blank" rel="noopener">www.baidu.com</a> 域名，操作系统会先检查自己本地的hosts文件是否有这个网址映射关系，如果有，就先调用这个ip地址映射，完成域名解析。</p>
<p>2、如果hosts里没有这个域名的映射，则会查找本地DNS解析器缓存，是否有这个网址映射关系，如果有，直接返回，完成域名解析。</p>
<p>3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系，首先会找TCP/IP参数中设置的首选DNS服务器，在此我们叫它本地DNS服务器，此服务器收到查询时，如果要查询的域名，包含在本地配置区域资源中，则返回解析记过给客户端，完成域名解析，此解析具有权威性。</p>
<p>4、如果要查询域名，不由本地DNS服务器区域解析，但该服务器已缓存了此网址映射关系，则调用这个IP地址映射，完成域名解析，此解析不具有权威性。</p>
<p>5、如果本地DNS服务器本地区域文件与缓存解析都失效，则根据本地DNS服务器的设置（是否设置转发器）进行查询，如果未用转发模式，本地DNS就把请求发至13台根DNS，根DNS服务器收到请求后会判断这个域名（.com）是谁来授权管理，并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后，将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后，如果自己无法解析，它就会找一个管理.com域的下一级DNS服务器地址（baidu.com）给本地DNS服务器。当本地DNS服务器收到这个地址后，就会找baidu.com域服务器，重复上面的动作，进行查询，直至找到<a href="http://www.baidu.com" target="_blank" rel="noopener">www.baidu.com</a> 主机。</p>
<p>6、如果用的是转发模式，此DNS服务器就会把请求转发至上一级DNS服务器，由上一级服务器进行解析，上一级服务器如果不能解析，或找根DNS或把请求转至上上级，以此循环。不管是本地DNS服务器用是转发，还是根提示，最后都是把结果返回给本地DNS服务器，由此DNS服务器再返回给客户机。</p>
</blockquote>
<h3 id="HTTP请求报文"><a href="#HTTP请求报文" class="headerlink" title="HTTP请求报文"></a>HTTP请求报文</h3><blockquote>
<p>http请求由三部分组成，分别是：请求行、请求报头、空行、请求数据</p>
<p>可以分别理解成我使用什么方法，我支持什么格式，我的格式说完了，我的正式数据</p>
</blockquote>
<p><img src="https://img2.jimu98.cn/blog/20200729170117.png" srcset="/img/loading.gif" alt="image-20200729170117264"></p>
<h4 id="请求行"><a href="#请求行" class="headerlink" title="请求行"></a>请求行</h4><blockquote>
<p>请求行由请求方法、URL字段和HTTP协议的版本组成，格式如下</p>
<p>Method     Request-URI      HTTP-Version     CRLF </p>
<p>其中 Method 表示请求方法；GET、POST、HEAD、PUT、DELETE、TRACE、CONNECT、OPTIONS（可选项）</p>
<p>Request-URI是一个统一资源标识符；（前面也说过了）</p>
<p>HTTP-Version表示请求的HTTP协议 版本；（后面说版本的区别）</p>
<p>CRLF表示回车和换行（除了作为结尾的CRLF外，不允许出现单独的CR或LF字符）。</p>
</blockquote>
<h4 id="请求报头"><a href="#请求报头" class="headerlink" title="请求报头"></a>请求报头</h4><blockquote>
<p>通用报头：（现在在解释请求报文，后面还有响应报文，他们两公用的报头）</p>
<p>Date：表示消息产生的日期和时间。<br>Connection：允许发送指定连接的选项。例如指定连接是连续的；或者指定“close”选项，通知服务器，在响应完成后，关闭连接。<br>Cache-Control：用于指定缓存指令，缓存指令是单向的（响应中出现的缓存指令在请求中未必会出现），且是独立的（一个消息的缓存指令不会影响另一个消息处理的缓存机制）。</p>
<p>//————————————————–</p>
<p>请求报头：（不同的报头在不同的http版本种诞生时间不同，可以看后面版本了解）</p>
<p>Host：请求的主机名，允许多个域名同处一个IP地址，即虚拟主机。<br>User-Agent：发送请求的浏览器类型、操作系统等信息。<br>Accept：客户端可识别的内容类型列表，用于指定客户端接收哪些类型的信息。<br>Accept-Charset请求报头域用于指定客户端接受的字符集 。<br>Accept-Encoding：客户端可识别的数据编码。<br>Accept-Language：表示浏览器所支持的语言类型。<br>Authorization请求报头域主要用于证明客户端有权查看某个资源。<br>Connection：允许客户端和服务器指定与请求/响应连接有关的选项。例如，这时为Keep-Alive则表示 保持连接。<br>Transfer-Encoding：告知接收端为了保证报文的可靠传输，对报文采用了什么编码方式。</p>
<p>//————————————————–</p>
<p>实体报头：（用来定义被传送数据的类型，既可用于请求，又可用于响应）</p>
<p>Content-Type：发送给接收者的实体正文的媒体类型。<br>Content-Lenght：实体正文的长度。<br>Content-Language：描述资源所用的自然语言。<br>Content-Encoding：实体报头被用作媒体类型的修饰符。它的值指示了已经被应用到实体正文的附加 内容的编码，因而要获得Content-Type报头域中所引用的媒体类型，必须采用相应的解码机制。<br>Last-Modified：实体报头用于指示资源的最后修改日期和时间。<br>Expires：实体报头给出响应过期的日期和时间。</p>
</blockquote>
<h4 id="空行"><a href="#空行" class="headerlink" title="空行"></a>空行</h4><blockquote>
<p>就是告诉服务器，我的请求头到此为止</p>
</blockquote>
<h4 id="请求数据"><a href="#请求数据" class="headerlink" title="请求数据"></a>请求数据</h4><blockquote>
<p>在get中，数据就在url中体现了，所以这里的数据指的在post提交中的数据，至于PUT、DELETE这些，他们其实也可以理解成post</p>
</blockquote>
<p><img src="https://img2.jimu98.cn/blog/20200729172717.png" srcset="/img/loading.gif" alt="image-20200729172717402"></p>
<h3 id="HTTP响应报文"><a href="#HTTP响应报文" class="headerlink" title="HTTP响应报文"></a>HTTP响应报文</h3><blockquote>
<p>HTTP 的响应报文由状态行、响应报头、空行、响应正文 （和请求体相当类似）</p>
</blockquote>
<h4 id="状态行"><a href="#状态行" class="headerlink" title="状态行"></a>状态行</h4><blockquote>
<p>就是告诉我们  请求的数据是否找到，如果没找到是因为啥，返回一些状态码（404大家都遇到过吧）</p>
</blockquote>
<pre><code class="hljs basic"><span class="hljs-number">1</span>xx：表明服务端接收了客户端请求，客户端继续发送请求；
<span class="hljs-number">2</span>xx：客户端发送的请求被服务端成功接收并成功进行了处理；
<span class="hljs-number">3</span>xx：服务端给客户端返回用于重定向的信息；
<span class="hljs-number">4</span>xx：客户端的请求有非法内容；
<span class="hljs-number">5</span>xx：服务端未能正常处理客户端的请求而出现意外错误。

<span class="hljs-number">2</span>xx:
<span class="hljs-symbol">200 </span>OK：表示从客户端发送给服务器的请求被正常处理并返回；
<span class="hljs-symbol">204 </span>No Content：表示客户端发送给客户端的请求得到了成功处理，但在返回的响应报文中不含实体的主体部分（没有资源可以返回）
<span class="hljs-symbol">206 </span>Patial Content：表示客户端进行了范围请求，并且服务器成功执行了这部分的<span class="hljs-keyword">GET</span>请求，响应报文中包含由Content-Range指定范围的实体内容。

<span class="hljs-number">3</span>xx:
<span class="hljs-symbol">301 </span>Moved Permanently：永久性重定向，表示请求的资源被分配了新的URL，之后应使用更改的URL；
<span class="hljs-symbol">302 </span>Found：临时性重定向，表示请求的资源被分配了新的URL，希望本次访问使用新的URL；
<span class="hljs-symbol">303 </span>See Other：表示请求的资源被分配了新的URL，应使用<span class="hljs-keyword">GET</span>方法定向获取请求的资源
<span class="hljs-symbol">304 </span><span class="hljs-keyword">Not</span> Modified：表示客户端发送附带条件（是指采用<span class="hljs-keyword">GET</span>方法的请求报文中包含<span class="hljs-keyword">if</span>-Match、<span class="hljs-keyword">If</span>-Modified-Since、<span class="hljs-keyword">If</span>-None-Match、<span class="hljs-keyword">If</span>-Range、<span class="hljs-keyword">If</span>-Unmodified-Since中任一首部）的请求时，服务器端允许访问资源，但是请求为满足条件的情况下返回改状态码；
<span class="hljs-symbol">307 </span>与<span class="hljs-number">302</span>相同，但不会把POST请求变成<span class="hljs-keyword">GET</span>

<span class="hljs-number">4</span>xx:
<span class="hljs-symbol">400 </span>Bad Request:表示请求报文中存在语法错误；
<span class="hljs-symbol">401 </span>Unauthorized：经许可，需要通过HTTP认证；
<span class="hljs-symbol">403 </span>Forbidden：服务器拒绝该次访问（访问权限出现问题）
<span class="hljs-symbol">404 </span><span class="hljs-keyword">Not</span> Found：表示服务器上无法找到请求的资源，除此之外，也可以在服务器拒绝请求但不想给拒绝原因时使用；

<span class="hljs-number">5</span>xx:
<span class="hljs-symbol">500 </span>Inter Server <span class="hljs-keyword">Error</span>：表示服务器在执行请求时发生了错误，也有可能是web应用存在的bug或某些临时的错误时；
<span class="hljs-symbol">503 </span>Server Unavailable：表示服务器暂时处于超负载或正在进行停机维护，无法处理请求；</code></pre>

<blockquote>
<p>突然想到某个老师教过，当你遇到404错误，你给用户返回一个503，显得你网站特别火爆（啊哈哈哈哈哈哈）</p>
<p>也就是说，其实看到某些状态码的时候，也不一定可信，因为后台可以改掉</p>
</blockquote>
<h3 id="Get与POST的区别"><a href="#Get与POST的区别" class="headerlink" title="Get与POST的区别"></a>Get与POST的区别</h3><blockquote>
<p>GET与POST是我们常用的两种HTTP Method（就是你在前端form表单那里写的，或者你后台用@PostMapping接收的那个）</p>
</blockquote>
<blockquote>
<ul>
<li>GET在浏览器回退时是无害的，而POST会再次提交请求。</li>
<li>GET产生的URL地址可以被收藏，而POST不可以。</li>
<li>GET请求会被浏览器主动cache，而POST不会，除非手动设置。</li>
<li>GET请求只能进行url编码，而POST支持多种编码方式。</li>
<li>GET请求参数会被完整保留在浏览器历史记录里，而POST中的参数不会被保留。</li>
<li>GET请求在URL中传送的参数是有长度限制的，而POST么有。</li>
<li>对参数的数据类型，GET只接受ASCII字符，而POST没有限制。</li>
<li>GET比POST更不安全，因为参数直接暴露在URL上，所以不能用来传递敏感信息。</li>
<li>GET参数通过URL传递，POST放在Request body中。</li>
</ul>
</blockquote>
<blockquote>
<p>但是，GET和POST的底层都是TCP/IP，你要给GET加上request body，给POST带上url参数，技术上是完全行的通的。</p>
<p>但是不同的浏览器对数据量有所限制，业界不成文的规定是，（大多数）浏览器通常都会限制url长度在2K个字节，而（大多数）服务器最多处理64K大小的url。</p>
<p>如果你用GET服务，在request body偷偷藏了数据，不同服务器的处理方式也是不同的，有些服务器会帮你卸货，读出数据，有些服务器直接忽略，所以，虽然GET可以带request body，也不能保证一定能被接收到。</p>
</blockquote>
<blockquote>
<p>还有一个比较重要的区别，很多面试笔记里面都没有写这一条（）</p>
<p>对于GET方式的请求，浏览器会把http header和data一并发送出去，服务器响应200（返回数据）；</p>
<p>而对于POST，浏览器先发送header，服务器响应100 continue，浏览器再发送data，服务器响应200 ok（返回数据）。</p>
<p>因为POST需要两步，时间上消耗的要多一点，看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。</p>
<p>并不是所有浏览器都会在POST中发送两次包，Firefox就只发送一次。</p>
<p>以上就是post和get全部区别的</p>
</blockquote>
<p><img src="https://img2.jimu98.cn/blog/20200729192410.png" srcset="/img/loading.gif" alt="image-20200729192410542"></p>
<p>其实HTTP协议中还⽀持着其他的⽅法，⽐如：Input、Delete、OPTIONS很多这样的⽅法。</p>
<p>⽽由于常⽤，于是我们也可能仅仅知道GET和POST⽅法了。 </p>
<p>HTTP提供⽅法的⽬的就是为了告知服务器该客户端想进⾏什么操作。当HTTP是OPTIONS⽅法的时候， 服务器端就会返回它⽀持什么HTTP⽅法。 当然了，现在RESTful盛⾏，也就是充分利⽤了HTTP协议的这些⽅法</p>
<p>RESTful  以后再专门总结一下（不然我怎么水博客）</p>
<h3 id="HTTP协议版本详解"><a href="#HTTP协议版本详解" class="headerlink" title="HTTP协议版本详解"></a>HTTP协议版本详解</h3><blockquote>
<p>版本这里有些枯燥，都是些知识点，作为了解可以跳过</p>
</blockquote>
<p>到现在为⽌，HTTP协议已经有四个版本了： </p>
<ul>
<li><p>HTTP/0.9</p>
<p>HTTP协议的最初版本，功能简陋，仅支持请求方式GET，并且仅能请求访问HTML格式的资源。</p>
</li>
<li><p>HTTP1.0</p>
<p>引入了新的命令POST和HEAD（http数据头部）命令，可自定义类型, 常见Content-Type值：text/xml image/jpeg audio/mp3</p>
<p>同时也开始支持cache，就是当客户端在规定时间内访问统一网站，直接访问cache即可。</p>
<p>但是1.0版本的工作方式是每次TCP连接只能发送一个请求，当服务器响应后就会关闭这次连接，下一个请求需要再次建立TCP连接，就是不支持keepalive。</p>
</li>
<li><p>HTTP1.1</p>
<p>新增方法：PUT、PATCH、OPTIONS、DELETE，引入了持久连接（persistent connection），即TCP连接默认不关闭，可以被多个请求复用，不用声明Connection: keep-alive。</p>
</li>
<li><p>HTTP/2</p>
<p>HTTP2.0是SPDY（谷歌公司研发的https的一种协议）的升级版<br>1.头信息和数据体都是二进制，称为头信息帧和数据帧<br>2.复用TCP连接，在一个连接里，客户端和浏览器都可以同时发送多个请求或回应，且不用按顺序一一对应，避免了“队头堵塞“,此双向的实时通信称为多工（Multiplexing）<br>3.引入头信息压缩机制（header compression）,头信息使用gzip或compress压缩后再发送；客户端和服务器同时维护一张头信息表，所有字段都会存入这个表，生成一个索引号，不发送同样字段，只发送索引号，提高速度<br>4.HTTP/2 允许服务器未经请求，主动向客户端发送资源，即服务器推送（server push）</p>
</li>
<li><p>HTTP/3 </p>
</li>
</ul>
<h4 id="HTTP1-0和HTTP1-1区别"><a href="#HTTP1-0和HTTP1-1区别" class="headerlink" title="HTTP1.0和HTTP1.1区别"></a>HTTP1.0和HTTP1.1区别</h4><blockquote>
<p>HTTP1.0和HTTP1.1最主要的区别就是： HTTP1.1默认是持久化连接！</p>
<p>在HTTP1.0默认是短连接：简单来说就是：每次与服务器交互，都需要新开⼀个连接！</p>
<p>在HTTP1.1中默认就使⽤持久化连接来解决：建⽴⼀次连接，多次请求均由这个连接完成！(如果阻塞 了，还是会开新的TCP连接的)</p>
</blockquote>
<blockquote>
<p>HTTP 1.1增加host字段</p>
</blockquote>
<blockquote>
<p>HTTP 1.1中引⼊了 Chunked transfer-coding ，范围请求，实现断点续传(实际上就是利⽤ HTTP消息头使⽤分块传输编码，将实体主体分块传输)</p>
</blockquote>
<blockquote>
<p>HTTP 1.1管线化(pipelining)理论，客户端可以同时发出多个HTTP请求，⽽不⽤⼀个个等待响应之 后再请求</p>
<p>仅仅是提出了理论，浏览器默认关闭HTTP pipelining！</p>
</blockquote>
<h4 id="HTTP2和HTTP1-1的区别"><a href="#HTTP2和HTTP1-1的区别" class="headerlink" title="HTTP2和HTTP1.1的区别"></a>HTTP2和HTTP1.1的区别</h4><h5 id="多工"><a href="#多工" class="headerlink" title="多工"></a>多工</h5><p>管线化(pipelining)和⾮管线化的区别：</p>
<p><img src="https://img2.jimu98.cn/blog/20200729163522.png" srcset="/img/loading.gif" alt="image-20200729163522493"></p>
<blockquote>
<p>HTTP Pipelining其实是把多个HTTP请求放到⼀个TCP连接中⼀⼀发送，⽽在发送过程中不需要等 待服务器对前⼀个请求的响应；只不过，客户端还是要按照发送请求的顺序来接收响应！</p>
</blockquote>
<blockquote>
<p>在HTTP1.0中，发送⼀次请求时，需要等待服务端响应了才可以继续发送请求。 在HTTP1.1中，发送⼀次请求时，不需要等待服务端响应了就可以发送请求了，但是回送数据给客户端的时候，客户端还是需要按照响应的顺序来⼀⼀接收 </p>
<p>所以说，⽆论是HTTP1.0还是HTTP1.1提出了Pipelining理论，还是会出现阻塞的情况。从专业的 名词上说这种情况，叫做线头阻塞（Head of line blocking）简称：HOLB</p>
</blockquote>
<blockquote>
<p>HTTP2与HTTP1.1最重要的区别就是解决了线头阻塞的问题！其中最重要的改动是：多路复⽤ (Multiplexing)</p>
</blockquote>
<p><img src="https://img2.jimu98.cn/blog/20200729164525.png" srcset="/img/loading.gif" alt="image-20200729164525340"></p>
<h5 id="二进制协议"><a href="#二进制协议" class="headerlink" title="二进制协议"></a>二进制协议</h5><blockquote>
<p>HTTP/1.1 版的头信息肯定是文本（ASCII编码），数据体可以是文本，也可以是二进制。HTTP/2 则是一个彻底的二进制协议</p>
</blockquote>
<h5 id="数据流"><a href="#数据流" class="headerlink" title="数据流"></a>数据流</h5><blockquote>
<p>HTTP/2 将每个请求或回应的所有数据包，称为一个数据流（stream）。每个数据流都有一个独一无二的编号。数据包发送的时候，都必须标记数据流ID，用来区分它属于哪个数据流。另外还规定，客户端发出的数据流，ID一律为奇数，服务器发出的，ID为偶数。</p>
</blockquote>
<h5 id="头信息压缩"><a href="#头信息压缩" class="headerlink" title="头信息压缩"></a>头信息压缩</h5><blockquote>
<p>HTTP 协议不带有状态，每次请求都必须附上所有信息。所以，请求的很多字段都是重复的，比如Cookie和User Agent，一模一样的内容，每次请求都必须附带，这会浪费很多带宽，也影响速度。</p>
<p>HTTP/2 对这一点做了优化，引入了头信息压缩机制（header compression）。一方面，头信息使用gzip或compress压缩后再发送；另一方面，客户端和服务器同时维护一张头信息表，所有字段都会存入这个表，生成一个索引号，以后就不发送同样字段了，只发送索引号，这样就提高速度了。</p>
</blockquote>
<h5 id="服务器推送"><a href="#服务器推送" class="headerlink" title="服务器推送"></a>服务器推送</h5><blockquote>
<p>HTTP/2 允许服务器未经请求，主动向客户端发送资源，这叫做服务器推送（server push）。</p>
</blockquote>
<h3 id="HTTP是不保存状态的协议"><a href="#HTTP是不保存状态的协议" class="headerlink" title="HTTP是不保存状态的协议"></a>HTTP是不保存状态的协议</h3><p>HTTP是⽆状态的，也就是说，它是不对通信状态进⾏保存的。它并不知道之前通信的对⽅是谁。这样 设计的⽬的就是为了让HTTP简单化，能够快速处理⼤量的事务！ </p>
<p>但是，我们经常是需要知道访问的⼈是谁，比如当用户往购物车中添加了商品，web 应用必须在用户浏览别的商品的时候仍保存购物车的状态，以便用户继续往购物车中添加商品。（你说保存在用户的数据库里面，那首先得登录吧，我们平时用的京东之类的购物网站可不是这样，未登录状态下就可以添加购物车）于是就有了Cookie技术了。 </p>
<h4 id="什么是Cookie？"><a href="#什么是Cookie？" class="headerlink" title="什么是Cookie？"></a>什么是Cookie？</h4><blockquote>
<p>cookie 是浏览器的一种缓存机制，它可用于维持客户端与服务器端之间的会话。由于下面一题会讲到session，所以这里要强调cookie会将会话保存在客户端（session则是把会话保存在服务端）</p>
</blockquote>
<blockquote>
<ol>
<li>首先用户在客户端浏览器向服务器发起登陆请求（或者不登录，但是第一次访问同样会给你一个cookie）</li>
<li>登陆成功后，服务端会把登陆的用户信息设置 cookie 中，返回给客户端浏览器</li>
<li>客户端浏览器接收到 cookie 请求后，会把 cookie 保存到本地（可能是内存，也可能是磁盘，看具体使用情况而定）</li>
<li>以后再次访问该 web 应用时，客户端浏览器就会把本地的 cookie 带上，这样服务端就能根据 cookie 获得用户信息了</li>
</ol>
</blockquote>
<h4 id="什么是session？"><a href="#什么是session？" class="headerlink" title="什么是session？"></a>什么是session？</h4><blockquote>
<p>刚才说的cookie一个重要概念就是保存在本地，那如果我想区分用户权限，有一个用户是普通用户，我给了他VIP1权限，并且保存在了他的CK里面，但是他自己改成了VIP15，然后我的网站判断这个人拥有全部权限。。。。。于是。。。。。。</p>
<p>很明显，这样是不安全的，于是，类似的又有了一个session的机制，session把会话内容保存在服务器端</p>
</blockquote>
<blockquote>
<ol>
<li>首先用户在客户端浏览器发起登陆请求</li>
<li>登陆成功后，服务端会把用户信息保存在服务端，并返回一个唯一的 session 标识给客户端浏览器。</li>
<li>客户端浏览器会把这个唯一的 session 标识保存在起来（一般保存在ck里面）</li>
<li>以后再次访问 web 应用时，客户端浏览器会把这个唯一的 session 标识带上，这样服务端就能根据这个唯一标识找到用户信息。</li>
</ol>
</blockquote>
<blockquote>
<p>大家会不会有一个疑问，说生成了一个session，又保存到了我的ck里面，那岂不是还是不安全，但是，我们可以抓包看一下</p>
</blockquote>
<p><img src="https://img2.jimu98.cn/blog/20200729195513.png" srcset="/img/loading.gif" alt="image-20200729195513482"></p>
<blockquote>
<p>我们能从这么一个字符串看出任何有效信息吗（一般来说，我们都能往服务器存数据了，应该没人往前台写隐私信息吧，emmmm<del>~</del>应该不会吧）他只是给了我们一个ID，有效信息都在服务器，他会根据我们的ID去服务器查找有效信息，然后返回对应内容。</p>
</blockquote>
<h4 id="session和cookie有什么区别"><a href="#session和cookie有什么区别" class="headerlink" title="session和cookie有什么区别"></a>session和cookie有什么区别</h4><blockquote>
<ol>
<li>cookie 是浏览器提供的一种缓存机制，它可以用于维持客户端与服务端之间的会话</li>
<li>session 指的是维持客户端与服务端会话的一种机制，它可以通过 cookie 实现，也可以通过别的手段实现。</li>
<li>如果用 cookie 实现会话，那么会话会保存在客户端浏览器中</li>
<li>而 session 机制提供的会话是保存在服务端的。</li>
</ol>
</blockquote>
<h2 id="HTTPS协议"><a href="#HTTPS协议" class="headerlink" title="HTTPS协议"></a>HTTPS协议</h2><blockquote>
<p>本块知识对细节要求较高，还是希望大家可以了解下ssl证书，以及非对称加密之类的概念</p>
<p>推荐先阅读码农翻身中关于https的小故事，然后再来理解https</p>
</blockquote>
<h3 id="Http的缺点"><a href="#Http的缺点" class="headerlink" title="Http的缺点"></a>Http的缺点</h3><blockquote>
<ol>
<li>通信使用明文不对数据进行加密（内容容易被窃听）</li>
<li>不验证通信方身份（容易伪装）</li>
<li>无法确定报文完整性（内容易被篡改）</li>
</ol>
<p>不安全：大家还记得我在计算机网络基础篇里面说的联网过程吗</p>
<p>从你家的网线出发，到小区的交换机，再到城市中央的路由器，再到小伙伴的小区交换机，再到小伙伴的电脑桌面。</p>
<p>任意一个环节都可以接入一台电脑，然后抓包，数据是可以被抓下来的。</p>
<p>比如我们传输一段 password：123456，那么黑客就直接可以看到了</p>
<p>但是我们传输一段 password：123456，使用加密技术之后 黑客可能看到的就是 E10ADC3949BA59ABBE56E057F20F883E</p>
</blockquote>
<blockquote>
<p>因此我们应该使用加密技术，但是码农翻身中 张大胖和Bill 的聊天，也指出了问题，如果中间人获取了他们的公钥，然后进行中间人攻击，那又失去了他的安全性。</p>
<p>于是乎，他们把自己的公钥交给，权威机构生成证书，权威机构在保证自己绝对安全的情况下，才能为整个互联网的安全做背书。</p>
</blockquote>
<h3 id="ssl证书"><a href="#ssl证书" class="headerlink" title="ssl证书"></a>ssl证书</h3><blockquote>
<p>SSL 协议就是用来解决 HTTP 传输过程的不安全问题，到了1999年，SSL 因为应用广泛，已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS（是“Transport Layer Security”的缩写），中文叫做“传输层安全协议”。</p>
<p>很多相关的文章都把这两者并列称呼（SSL/TLS），因为这两者可以视作同一个东西的不同阶段。</p>
<p>（个人认为，大家还是喜欢把他叫做SSL，不信你去百度搜索下SSL证书和TLS证书，看看哪个广告多）</p>
<p>SSL/TLS协议的基本思路是采用公钥加密法，也就是说，客户端先向服务器端索要公钥，然后用公钥加密信息，服务器收到密文后，用自己的私钥解密。</p>
</blockquote>
<p>SSL/TLS协议的基本过程是这样的</p>
<blockquote>
<ol>
<li>服务端将非对称加密的公钥发送给客户端；</li>
<li>客户端拿着服务端发来的公钥，对对称加密的key做加密并发给服务端；</li>
<li>服务端拿着自己的私钥对发来的密文解密，从来获取到对称加密的key；</li>
<li>二者利用对称加密的key对需要传输的消息做加解密传输。</li>
</ol>
</blockquote>
<p>然后我们来看HTTPS</p>
<h3 id="HTTPS"><a href="#HTTPS" class="headerlink" title="HTTPS"></a>HTTPS</h3><p>HTTPS=HTTP+SSL</p>
<p>HTTPS也就是披着SSL羊皮的HTTP</p>
<p>HTTPS相比HTTP，在请求前多了一个「握手」的环节。</p>
<h3 id="Http与Https的区别"><a href="#Http与Https的区别" class="headerlink" title="Http与Https的区别"></a>Http与Https的区别</h3><blockquote>
<ul>
<li>HTTP 明文传输，数据都是未加密的，安全性较差，HTTPS（SSL+HTTP） 数据传输过程是加密的，安全性较好。</li>
<li>使用 HTTPS 协议需要到 CA（Certificate Authority，数字证书认证机构） 申请证书，一般免费证书较少，因而需要一定费用。证书颁发机构如：Symantec、Comodo、GoDaddy 和 GlobalSign 等。</li>
<li>HTTP 页面响应速度比 HTTPS 快，主要是因为 HTTP 使用 TCP 三次握手建立连接，客户端和服务器需要交换 3 个包，而 HTTPS除了 TCP 的三个包，还要加上 ssl 握手需要的 9 个包，所以一共是 12 个包。</li>
<li>http 和 https 使用的是完全不同的连接方式，用的端口也不一样，前者是 80，后者是 443。</li>
<li>HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议，所以，要比较 HTTPS 比 HTTP 要更耗费服务器资源。</li>
</ul>
</blockquote>
<blockquote>
<p>个人觉得，这个HTTPS加密流程作用性价比不高</p>
<p>又废资源又费钱（我用的免费的。。。）</p>
<p>而且我访问一个网站，黑客真的会在中间截获数据吗，我觉得更应该从源头或者目的来截获吧（可能是我网络安全知识薄弱，不太懂）</p>
<p>而且很明显，多了9次握手，那速度势必会影响 emmmm。。。</p>
</blockquote>

            </article>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/java%E6%80%BB%E7%BB%93/">java总结</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a>
                    
                      <a class="hover-with-bg" href="/tags/HTTP/">HTTP</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" target="_blank" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <div class="post-prev col-6">
                    
                    
                  </div>
                  <div class="post-next col-6">
                    
                    
                      <a href="/2020/07/28/java/%E3%80%90Java%E6%80%BB%E7%BB%93%E3%80%91%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">
                        <span class="hidden-mobile">【java总结】计算机网络-基础篇</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </div>
                </div>
              
            </div>

            
              <!-- Comments -->
              <div class="comments" id="comments">
                
                
  <div id="vcomments"></div>
  <script type="text/javascript">
    function loadValine() {
      addScript('https://cdn.staticfile.org/valine/1.4.14/Valine.min.js', function () {
        new Valine({
          el: "#vcomments",
          app_id: "NFojgagn3zsFUjT0FGVVHUTM-gzGzoHsz",
          app_key: "9R1L32c7WEvSGSP48NAnfStY",
          placeholder: "说点什么",
          path: window.location.pathname,
          avatar: "retro",
          meta: ["nick","mail","link"],
          pageSize: "10",
          lang: "zh-CN",
          highlight: false,
          recordIP: true,
          serverURLs: "https://nfojgagn.lc-cn-n1-shared.com",
        });
      });
    }
    createObserver(loadValine, 'vcomments');
  </script>
  <noscript>Please enable JavaScript to view the <a href="https://valine.js.org" target="_blank" rel="nofollow noopener noopener">comments
      powered by Valine.</a></noscript>


              </div>
            
          </div>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
  <p id="hitokoto">:D 获取中...</p>
<script>
  fetch('https://v1.hitokoto.cn')
    .then(response => response.json())
    .then(data => {
      const hitokoto = document.getElementById('hitokoto')
      hitokoto.innerText = data.hitokoto
      })
      .catch(console.error)
</script>
   <div>
  <span id="timeDate">载入天数...</span>
  <span id="times">载入时分秒...</span>
  <script>
  var now = new Date();
  function createtime(){
      var grt= new Date("07/18/2020 18:00:00");//此处修改你的建站时间或者网站上线时间
      now.setTime(now.getTime()+250);
      days = (now - grt ) / 1000 / 60 / 60 / 24;
      dnum = Math.floor(days);
      hours = (now - grt ) / 1000 / 60 / 60 - (24 * dnum);
      hnum = Math.floor(hours);
      if(String(hnum).length ==1 ){
          hnum = "0" + hnum;
      }
      minutes = (now - grt ) / 1000 /60 - (24 * 60 * dnum) - (60 * hnum);
      mnum = Math.floor(minutes);
      if(String(mnum).length ==1 ){
                mnum = "0" + mnum;
      }
      seconds = (now - grt ) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum);
      snum = Math.round(seconds);
      if(String(snum).length ==1 ){
                snum = "0" + snum;
      }
      document.getElementById("timeDate").innerHTML = "本站安全运行&nbsp"+dnum+"&nbsp天";
      document.getElementById("times").innerHTML = hnum + "&nbsp小时&nbsp" + mnum + "&nbsp分&nbsp" + snum + "&nbsp秒";
  }
  setInterval("createtime()",250);
  </script>
</div>
    <div>
      &copy;2019 - 2020 By Jimu98
    </div>
    

    
  <!-- 备案信息 -->
  <div class="beian">
		
          <img src="/img/police_beian.png" srcset="/img/loading.gif" alt="police-icon" />
        
    <a href="http://beian.miit.gov.cn/" target="_blank"
       rel="nofollow noopener">冀ICP备19035627号</a>
    
  </div>


    
      <!-- cnzz Analytics Icon -->
      <span id="cnzz_stat_icon_1278280985" style="display: none"></span>
    
  </div>

</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/lazyload.js" ></script>
  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/js/clipboard-use.js" ></script>







  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: 'article.markdown-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 0,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "【java总结】计算机网络-HTTP&nbsp;",
      ],
      cursorChar: "|",
      typeSpeed: 95,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    var path = "/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>







  
  
    <script>
      !function (e, t, a) {
        function r() {
          for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x + "px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e].scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999");
          requestAnimationFrame(r)
        }

        function n() {
          var t = "function" == typeof e.onclick && e.onclick;
          e.onclick = function (e) {
            t && t(), o(e)
          }
        }

        function o(e) {
          var a = t.createElement("div");
          a.className = "heart", s.push({
            el: a,
            x: e.clientX - 5,
            y: e.clientY - 5,
            scale: 1,
            alpha: 1,
            color: c()
          }), t.body.appendChild(a)
        }

        function i(e) {
          var a = t.createElement("style");
          a.type = "text/css";
          try {
            a.appendChild(t.createTextNode(e))
          } catch (t) {
            a.styleSheet.cssText = e
          }
          t.getElementsByTagName("head")[0].appendChild(a)
        }

        function c() {
          return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"
        }

        var s = [];
        e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (e) {
          setTimeout(e, 1e3 / 60)
        }, i(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"), n(), r()
      }(window, document);
    </script>
  











  

  

  

  

  

  
    <!-- cnzz Analytics -->
    <script defer src="//s4.cnzz.com/z_stat.php?id=1278280985&show=pic"
            type="text/javascript"></script>
  





</body>
</html>
